package com.tjetc;

import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.dom4j.tree.DefaultElement;

import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * 读取xml文件 并建立连接
 *
 * @author gaoyongxiang
 * @version v1.0
 * @date 2025/8/20
 */
public class MyConfiguration {
    // 类加载器
    private static ClassLoader classLoader = ClassLoader.getSystemClassLoader();

    /**
     * 获取连接
     *
     * @param resource 配置文件的名称
     * @return 数据库连接
     */
    public Connection build(String resource) throws DocumentException, SQLException, ClassNotFoundException {
        Connection connection = null;
        // 把配置文件加载到内存
        InputStream in = classLoader.getResourceAsStream(resource);
        // 使用dom4j进行解析
        SAXReader reader = new SAXReader();
        // 将流读到一个文档对象中
        Document doc = reader.read(in);
        // 拿到文档中的根节点
        Element rootElement = doc.getRootElement();
//        System.out.println(rootElement);
        // 开始解析这个文档树 封装一个方法专门用来解析树结构
        connection = parseXMLStructure(rootElement);
//        System.out.println(connection);
        return connection;
    }

    /**
     * 根据根节点解析树结构并获取数据库连接
     *
     * @param rootElement 根节点
     * @return 数据库连接
     */
    private Connection parseXMLStructure(Element rootElement) throws ClassNotFoundException, SQLException {
        // 拿到我们需要连接数据库的四个参数
        List<Element> propertyList = rootElement.elements("property");
        // 四个数据库对应的属性值
        String driverClassName = null;
        String url = null;
        String username = null;
        String password = null;
        for (Element element : propertyList) {
//            System.out.println(element);
            String name = element.attributeValue("name");
            String value = element.attributeValue("value");
//            System.out.println(name + value);

            // 根据获取的值进行赋值  可以通过switch case 来根据不同值进行赋值
            switch (name) {
                case "url":
                    url = value;
                    break;
                case "driverClassName":
                    driverClassName = value;
                    break;
                case "username":
                    username = value;
                    break;
                case "password":
                    password = value;
                    break;
                default:
            }
        }
        // 根据四大参数连接数据库
//            Class.forName(driverClassName);
        return DriverManager.getConnection(url, username, password);
    }

    /**
     * 将mapper.xml读取到对象中
     *
     * @param path mapper的位置 这里简化操作 省略了获取mapper节点的过程 直接读
     * @return
     */
    public MapperBean readMapper(String path) throws DocumentException {
        MapperBean mapperBean = new MapperBean();
        // 把配置文件加载到内存
        InputStream in = classLoader.getResourceAsStream(path);
        // 使用dom4j进行解析
        SAXReader reader = new SAXReader();
        // 将流读到一个文档对象中
        Document doc = reader.read(in);
        // 拿到文档中的根节点  mapper
        Element rootElement = doc.getRootElement();

        // 获取namespace
        String namespace = rootElement.attributeValue("namespace").trim();
        mapperBean.setInterfaceName(namespace);

        // 通过迭代器获取到select节点中的信息
        Iterator iterator = rootElement.elementIterator();
        // 方法信息的集合
        List<Function> functionList = new ArrayList<>();
        while (iterator.hasNext()) {
            Element element = (Element) iterator.next();
            // 创建Function对象 记录方法信息
            Function function = new Function();
            // 拿到select
            String sqlType = element.getName().trim();
            // 拿到selectBankById
            String functionName = element.attributeValue("id").trim();
            // 拿到int
            String parameterType = element.attributeValue("parameterType").trim();
            // 拿到com.tjetc.Bank
            String resultType = element.attributeValue("resultType").trim();
            // 拿到sql select * from bank where id = ?
            String sql = element.getText().trim();
            // 开始封装 这个过程一定是反射
            function.setFunctionName(functionName);
            function.setParameterType(parameterType);
            function.setResultType(resultType);
            function.setSql(sql);
            function.setSqlType(sqlType);
            // 将封装好的function对象 加到list集合中
            functionList.add(function);
        }
        // 循环结束后 functionList 装载完毕
        mapperBean.setFunctionList(functionList);
        return mapperBean;

    }

}